home *** CD-ROM | disk | FTP | other *** search
/ Games of Daze / Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso / x2ftp / msdos / libs / 3dvect39 / 3d2.asm < prev    next >
Assembly Source File  |  1994-10-30  |  36KB  |  1,172 lines

  1. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  2. ;
  3. ; Filename     : 3d2.asm
  4. ; Included from: Main Assembley Module
  5. ; Description  : 3d vector routines full sorting method (slower)
  6. ;
  7. ; Written by: John McCarthy
  8. ;             1316 Redwood Lane
  9. ;             Pickering, Ontario.
  10. ;             Canada, Earth, Milky Way (for those out-of-towners)
  11. ;             L1X 1C5
  12. ;
  13. ; Internet/Usenet:  BRIAN.MCCARTHY@CANREM.COM
  14. ;         Fidonet:  Brian McCarthy 1:229/15
  15. ;   RIME/Relaynet: ->CRS
  16. ;
  17. ; Home phone, (905) 831-1944, don't call at 2 am eh!
  18. ;
  19. ; Send me your protected mode source code!
  20. ; Send me your Objects!
  21. ; But most of all, Send me a postcard!!!!
  22. ;
  23. ; - objects can pass through one another and still be sorted correctly
  24. ; - maxsurfs and maxpoints must be large - set to TOTAL points/surfs on screen
  25. ;
  26. ; To use:
  27. ;
  28. ;          call _land_draw          ; draw _background landscape
  29. ;          call _clearfill          ; clear video memory (last screen)
  30. ;          call _look_at_it         ; make camera look at selected object
  31. ;          call _setsincose         ; set rotation multipliers for eye
  32. ;          call _star_plot          ; plot _background stars (if you want)
  33. ;          call _makeobjs           ; plot all objects in sides table
  34. ;          call _instant_mouse      ; plot mouse on screen
  35. ;          call _flip_page          ; flip video pages
  36. ;          call _updvectors         ; move objects around, _rotate_point them
  37. ;
  38. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  39.  
  40.          .386p
  41.          jumps
  42.  
  43. code32   segment para public use32
  44.          assume cs:code32, ds:code32
  45.  
  46. ; define externals
  47.  
  48.          include pmode.ext                  ; protected mode externals
  49.          include xmode.ext                  ; xmode externals by matt pritchard
  50.          include irq.ext
  51.  
  52.          extrn _nullpalette:dword
  53.  
  54.          include macros.inc
  55.          include equ.inc
  56.  
  57.          include vars2.inc                  ; labels and such
  58.          align 4
  59.          include tables.inc
  60.          include math.inc                   ; _rotate_point, cos,sin,arctan...
  61.          include xscale.inc
  62.          include poly.inc                   ; common ploygon stuff
  63.  
  64.          public _makeobjs
  65.          public _make1obj
  66.          public _flush_surfaces
  67.          public _init_tables
  68.  
  69.          strip_bytes equ 4
  70.  
  71.          align 4
  72.  
  73. abort_all:
  74.          add esp,strip_bytes                ; abort from loadpoints and _make1obj
  75.          ret                                ; returning now from _makeobjs call
  76.  
  77.          align 4
  78.  
  79. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  80. ; Loadpoints:  Begin loading of points from object definition data into array
  81. ; In:
  82. ;  ESI -> object #
  83. ; Out:
  84. ;  ESI -> offset of connection data
  85. ; Given ESI as object number.  _rotate_point, translate and convert to 3d the points
  86. ; of that object.  returns edi as pointer to sides.
  87. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  88.  
  89. loadpoints:
  90.          mov bl,v_userotate[esi]             ; rotation type
  91.  
  92.          mov si,v_whatshape[esi*2]           ; get shape
  93.          mov esi,_objbase[esi*4]
  94.  
  95. view_is_not_ok:
  96.          mov eax,[esi]
  97.          add esi,8
  98.  
  99.          cmp eax,zad                        ; check if too far to see detail anyway
  100.          jb s view_is_not_ok
  101.  
  102.          mov eax,[esi-4]
  103.          add esi,eax
  104. llkk:
  105.          movzx eax,w [esi]
  106.          mov numpoints,eax
  107.  
  108.          or eax,eax
  109.          jz no_points_anyway
  110.  
  111.          mov edi,pointindex                 ; set xp,yp,zp pointer
  112.  
  113.          shl eax,2
  114.          add eax,pointindex                 ; pointindex = word indexer to last point
  115.          cmp eax,maxpoints*4-4              ; test for overflow in points tables
  116.          jae abort_all
  117.  
  118.          mov ax,[esi+2]
  119.          mov numsides,eax
  120.  
  121.          add eax,_showing
  122.          cmp eax,maxsurfaces-1              ; check for overflow in "sides" tables
  123.          jae abort_all
  124.  
  125.          add esi,4+25*2                     ; skip point and side totals, skip future data
  126.          mov lindex,edi                     ; set last index to points (this one)
  127.  
  128.          add edi,4                          ; compensate for center of gravity point
  129. middle_load_points:
  130.          test bl,no_rotation                ; check v_userotate command
  131.          jnz np13                           ; use different loop if no rotation
  132. np12:
  133.          movsx ebx,w [esi]                  ; x
  134.          movsx ecx,w [esi+2]                ; y
  135.          movsx ebp,w [esi+4]                ; z
  136.  
  137.          push edi esi
  138.          call _rotate_point                 ; _rotate_point based on object matrix
  139.          add ebp,zad
  140.  
  141.          cmp ebp,ztruncate
  142.          jl s ntrt
  143. ntrunct:
  144.          add ebx,xad
  145.          add ecx,yad
  146.          call _make3d
  147.          pop esi edi
  148.          mov xp[edi],ebx
  149.          mov yp[edi],ecx
  150.          mov zp[edi],ebp
  151.          add edi,4                          ; inc xp indexer
  152.          add esi,6                          ; inc input pointer
  153.          dec numpoints
  154.          jne s np12
  155.  
  156.          mov pointindex,edi                 ; save for next call of loadpoints
  157.  
  158.          ret                                ; esi exits with pointer to sides
  159. ntrt:
  160.          mov ebp,ztruncate
  161.          jmp s ntrunct
  162.  
  163. no_points_anyway:
  164.          mov ax,[esi+2]
  165.          mov numsides,eax
  166.  
  167.          add eax,_showing
  168.          cmp eax,maxsurfaces-1              ; check for overflow in "sides" tables
  169.          jae abort_all
  170.  
  171.          add esi,4+25*2                     ; skip point and side totals, skip future data
  172.  
  173.          mov edi,pointindex                 ; set xp,yp,zp pointer
  174.          add pointindex,4
  175.          mov lindex,edi                     ; set last index to points (this one)
  176.          ret
  177. np13:
  178.          movsx ebx,w [esi]                  ; x
  179.          movsx ecx,w [esi+2]                ; y
  180.          movsx ebp,w [esi+4]                ; z
  181.  
  182.          push edi esi
  183.          call _rotate_by_camera             ; rotation matrix already set up! (camera)
  184.          add ebp,zad
  185.  
  186.          cmp ebp,ztruncate
  187.          jge s ntrt2
  188. ntrunct2:
  189.          add ebx,xad
  190.          add ecx,yad
  191.          call _make3d
  192.          pop esi edi
  193.          mov xp[edi],ebx
  194.          mov yp[edi],ecx
  195.          mov zp[edi],ebp
  196.          add edi,4                          ; inc xp indexer
  197.          add esi,6
  198.          dec numpoints
  199.          jne s np13
  200.  
  201.          mov pointindex,edi                 ; save for next call of loadpoints
  202.  
  203.          ret
  204. ntrt2:
  205.          mov ebp,ztruncate
  206.          jmp s ntrunct2
  207.  
  208.          align 4
  209.  
  210. special_commands dd offset do_bitmap
  211.          dd offset do_bitmap
  212.          dd offset pushmatrix
  213.          dd offset popmatrix
  214.          dd offset pushlocation
  215.          dd offset poplocation
  216.          dd offset newobject
  217.          dd offset no_new_matrix
  218.          dd offset gosub_function           ; 8
  219.          dd offset return_function          ; 9
  220.          dd offset goto_function            ; 10
  221.  
  222. number_ofb dw 5*2
  223.          dw 5*2
  224.          dw 1*2
  225.          dw 1*2
  226.          dw 1*2
  227.          dw 1*2
  228.          dw 1*2
  229.          dw 1*2
  230.          dw ?                               ; gosub_function
  231.          dw ?                               ; return_function
  232.          dw ?                               ; goto_function
  233.  
  234.          align 4
  235. gosub_function:
  236.          push esi
  237.          movsx eax,w [esi]
  238.          add esi,eax
  239.          jmp return_iteration
  240.  
  241.          align 4
  242. return_function:
  243.          pop esi
  244.          add esi,2
  245.          jmp return_iteration
  246.  
  247.          align 4
  248. goto_function:
  249.          movsx eax,w [esi]
  250.          add esi,eax
  251.          jmp return_iteration
  252.  
  253.          align 4
  254. pushmatrix:
  255.          push _vmatrix+0
  256.          push _vmatrix+4
  257.          push _vmatrix+8
  258.          push _vmatrix+12
  259.          push _vmatrix+16
  260.          push _vmatrix+20
  261.          push _vmatrix+24
  262.          push _vmatrix+28
  263.          push _vmatrix+32
  264.          jmp return_iteration
  265.  
  266.          align 4
  267. popmatrix:
  268.          pop _vmatrix+32
  269.          pop _vmatrix+28
  270.          pop _vmatrix+24
  271.          pop _vmatrix+20
  272.          pop _vmatrix+16
  273.          pop _vmatrix+12
  274.          pop _vmatrix+8
  275.          pop _vmatrix+4
  276.          pop _vmatrix+0
  277.          jmp return_iteration
  278.  
  279.          align 4
  280. pushlocation:
  281.          push xad
  282.          push yad
  283.          push zad
  284.          jmp return_iteration
  285.  
  286.          align 4
  287. poplocation:
  288.          pop zad
  289.          pop yad
  290.          pop xad
  291.          jmp return_iteration
  292.  
  293.          align 4
  294. ld_special:
  295.          mov cx,ax
  296.          and ecx,special-1                  ; max 127 commands
  297.          jmp [special_commands+ecx*4]
  298.  
  299.          align 4
  300.  
  301. ; handle loading of _bitmap from object list
  302. ;
  303. ; eg dw himap,8,5,50,60 ;command is 32,point 8, _bitmap 5, x&y scaling of 50,60
  304.  
  305. do_bitmap:
  306.          align 4
  307.  
  308.          lodsw                              ; get from si, first is point
  309.          shl eax,2
  310.          add eax,lindex                     ; add to include offset in list
  311.          stosw                              ; put in sides table
  312.  
  313.          mov edx,ebp                        ; save indexer
  314.          movzx ebp,ax                       ; get point indexers
  315.          mov eax,zp[ebp]
  316.          mov zeds[ebx*2],eax                ; set zed for sort.
  317.          mov ebp,edx
  318.  
  319.          movsw                              ; get _bitmap type
  320.          movsd                              ; get x then y scaling
  321.  
  322.          mov edx,command                    ; get command (for iteration bits)
  323.          mov textures[ebx],dx
  324.  
  325.          cmp zad,64000                      ; _bitmaps farther than 65536 screw up
  326.          jge no_norml                       ; you can't see them anyway. prevent overflow
  327.          jmp ln3
  328.  
  329.          align 4
  330.  
  331. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  332. ; Loadsides: Load connection data from object data definition
  333. ; In:
  334. ;  ESI -> offset of connection data
  335. ; Out: null
  336. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  337.  
  338. loadsides:
  339.          mov lamflag,no
  340.          mov edi,offsides                   ; get ready for lodsw and stosw
  341.          mov ebp,edi                        ; ebp = offset to first point in side
  342.          mov ebx,_showing                   ; bx = word indexer for surfaces
  343.          shl ebx,1
  344. ld_lp:
  345.          mov ax,[esi]                       ; get command word
  346.          add esi,2
  347.          mov command,eax
  348.  
  349.          test eax,special                   ; if _bitmap, do special load,
  350.          jnz ld_special                     ; or test previous color
  351.  
  352.          mov eax,[esi]                      ; get texture data/type
  353.          mov texture12,eax
  354.  
  355.          mov eax,[esi+4]                    ; get colour, high byte is other side
  356.          add esi,8
  357.          mov colors12,eax
  358.  
  359.          mov ecx,lindex                     ; quick add for loop
  360.  
  361.          push ebp
  362.          push ebx
  363.  
  364.          movzx eax,w [esi]                  ; get from esi, first is unconditinal
  365.          add esi,2
  366.          shl eax,2
  367.          add eax,ecx                        ; add to include offset in list
  368.          mov [edi],ax                       ; put in edi
  369.          mov [edi+4],ax
  370.          mov edx,eax
  371.  
  372.          lodsw                              ; get from esi
  373.          shl eax,2
  374.          add eax,ecx
  375.          mov [edi+2],ax                     ; put in edi
  376.          mov [edi+6],ax
  377.          cmp eax,edx                        ; check all after first point
  378.          je s ld_exitloop
  379.          add edi,4
  380. ld_loop:
  381.          lodsw
  382.          shl eax,2
  383.          add eax,ecx
  384.          mov [edi+0],ax
  385.          cmp eax,edx
  386.          je s ld_exitloop
  387.  
  388.          lodsw
  389.          shl eax,2
  390.          add eax,ecx
  391.          mov [edi+2],ax
  392.          cmp eax,edx
  393.          je s ld_exitloop
  394.  
  395.          lodsw
  396.          shl eax,2
  397.          add eax,ecx
  398.          mov [edi+4],ax
  399.          add edi,6
  400.          cmp eax,edx
  401.          jne s ld_loop
  402.  
  403. ld_exitloop:
  404.          push esi
  405.  
  406.          mov edi,ebp                        ; adjust bp into appropriate indexer
  407.  
  408.          movzx ebp,w [edi+6]
  409.          mov ecx,[zp+ebp]
  410.          mov bp,[edi+4]
  411.          add ecx,[zp+ebp]
  412.          mov bp,[edi+2]
  413.          add ecx,[zp+ebp]
  414.          mov ebp,edx                        ; get point indexers
  415.          add ecx,[zp+ebp]                   ; take average of two z points for sort
  416.          mov zeds[ebx*2],ecx
  417.  
  418.          mov edx,command
  419.  
  420.          test edx,onscr                     ; find if test is for on screen pixels
  421.          jnz test_if_on_screen
  422.          test dl,both                       ; check if always visible
  423.          jnz its_line
  424.  
  425. return_screen:
  426.          mov edx,[xp+ebp]                   ; first point
  427.          mov ebx,[yp+ebp]
  428.  
  429.          mov bp,[edi+2]
  430.          mov esi,[xp+ebp]                   ; second point
  431.          mov ecx,[yp+ebp]
  432.  
  433.          mov bp,[edi+4]
  434.          mov edi,[xp+ebp]                   ; third point
  435.          mov ebp,[yp+ebp]
  436.  
  437.          call checkfront                    ; check if side is visable using p1,2,3
  438.  
  439.          pop esi ebx ebp                    ; return object data pointer
  440.  
  441.          mov edx,command
  442.          or ecx,ecx
  443.          jle s test_shading                 ; cx>-1 if side visible, skip if not
  444.          test edx,double                    ; test to use other colour
  445.          jz s skipit                        ; miss this side...
  446.          shr texture12,16
  447.          shr colors12,16
  448.          xor w texture12,inverse            ; do inverse shading
  449. test_shading:
  450.          test texture12,shade+last
  451.          jnz handle_shading                 ; shading bit set, do it...
  452. ln2:
  453.          test edx,check                     ; find out if side is only a test side
  454.          jnz s no_show
  455.  
  456.          mov eax,texture12                  ; another side added...
  457.          mov textures[ebx],ax
  458.          movzx eax,w colors12
  459.          add eax,palxrefx                  ; get offset of palette cross reference table for this object
  460.          mov ax,[eax]
  461.          mov surfcolors[ebx],ax
  462. ln3:
  463.          inc _showing                       ; another side added...
  464.          add ebx,2
  465.          add ebp,maxpolys*2                 ; bump ebp to next block
  466. no_show:
  467.          test edx,iterate
  468.          jnz handle_surface_iteration
  469. skipit:
  470.          test edx,normal                    ; do we skip surface normal data
  471.          jz s no_norml
  472.          add esi,6
  473. no_norml:
  474.          test edx,iterate
  475.          jnz failed_iteration               ; skip iteration data if surface failure
  476.  
  477. return_iteration:
  478.          mov edi,ebp                        ; set di for next stosw
  479.  
  480.          dec numsides                       ; count for next side
  481.          jne ld_lp
  482.  
  483.          mov offsides,edi                   ; save for next call
  484.  
  485.          ret
  486.  
  487.          align 4
  488. its_line:
  489.          pop esi ebx ebp
  490.          test w texture12,shade+last
  491.          jz ln2
  492.  
  493. ; handle gourad/_lambert shading
  494.  
  495.          align 4
  496. handle_shading:
  497.          test w texture12,last              ; test to use previous colour or _bitmap call
  498.          jnz ld_do_previous
  499.  
  500.          test w texture12,wavey
  501.          jnz ln2
  502.  
  503.          push ebx esi ebp edx
  504.  
  505.          cmp lamflag,no                     ; is _lambert matrix set up?
  506.          je s setitup                       ; jump to less likely route
  507. returnq:
  508.          mov bx,word ptr [esi]              ; get surface normal
  509.          mov cx,word ptr [esi+2]
  510.          mov bp,word ptr [esi+4]
  511.          add esi,6
  512.          call _l_rotate_point               ; _rotate_point surface normal by _lambert matrix
  513.  
  514.          pop edx
  515.          test w texture12,inverse           ; have the sides flipped? test dx,256
  516.          jnz s invert_colour                ; jump to least likely route
  517. lp_contin:
  518.          add edi,256
  519.          shr edi,1                          ; result -256 to +256, turn into 0-256
  520.          mov al,b shading_tables[edi]       ; now into 0-15
  521.          xor ah,ah
  522.          mov lastshade,al
  523.  
  524.          pop ebp esi ebx
  525.  
  526.          add w colors12,ax                  ; user can have offset color in object!
  527.  
  528.          jmp ln2
  529.  
  530.          align 4
  531. invert_colour: ; inversion occures with other side option,
  532.          neg edi                            ; always visible option, and shading option
  533.          jmp lp_contin                      ; all combined!
  534.  
  535.          align 4
  536. setitup:
  537.          push esi
  538.          mov esi,currobj                    ; this is object # from _make1obj
  539.          call _lambert                      ; set up _lambert maxtrix
  540.          mov lamflag,yes
  541.          pop esi
  542.          jmp s returnq
  543.  
  544.          align 4
  545.  
  546. ld_do_previous:
  547.          mov al,lastshade                   ; use colour from previous calculation
  548.          add b colors12,al
  549.          jmp ln2
  550.  
  551. ; handle iteration option
  552.  
  553.          align 4
  554.  
  555. handle_surface_iteration:
  556.          test edx,normal
  557.          jz s no_norml2
  558.          add esi,6                          ; skip if shading normal present
  559. no_norml2:
  560.          test edx,matrix                    ; test to derive new matrix
  561.          jz no_new_matrix
  562. newobject:
  563.          mov edi,currobj                    ; new matrix, get offset object number
  564.          add di,[esi+16]
  565.          test v_onoff[edi],sub_object_on     ; test if sub-object has been turned on...
  566.          jz failed_iteration
  567.  
  568.          mov eax,[esi+24]
  569.          mov minzc,eax
  570.          mov eax,[esi+28]
  571.          mov btolr,eax
  572.          push ebx esi ebp edx               ; save stuff before iteration handle
  573.  
  574.          mov bx,w v_xs[edi*4]                ; get rotation location
  575.          mov cx,w v_ys[edi*4]
  576.          mov bp,w v_zs[edi*4]
  577.          add bx,[esi+10]
  578.          add cx,[esi+12]
  579.          add bp,[esi+14]
  580.          movsx ebx,bx
  581.          movsx ecx,cx
  582.          movsx ebp,bp
  583.  
  584.          push edi
  585.          call _rotate_point                 ; z<>0, find rotation location
  586.  
  587.          add xad,ebx
  588.          add yad,ecx
  589.          add zad,ebp
  590.  
  591.          pop esi                            ; return object number+offset
  592.          test v_userotate[esi],no_rotation   ; test to use new matrix or add to old
  593.          jnz do_compound_thingy
  594.          call _temp_matrix                  ; add to old
  595.          call _matrix_multiply
  596.          mov eax,minzc
  597.          cmp zad,eax                        ; check if new object will be behind camera
  598.          jg done_alterq
  599.          jmp failed_iterationq
  600.  
  601. do_compound_thingy:
  602.          call _compound                     ; _compound new matrix
  603.          mov eax,minzc
  604.          cmp zad,eax                        ; check if new object will be behind camera
  605.          jg done_alterq
  606.          jmp failed_iterationq
  607.  
  608. no_new_matrix:
  609.          test b [esi+8],centroid            ; is there a centroid offset?
  610.          jz done_alter
  611.          mov eax,[esi+28]
  612.          mov btolr,eax
  613.  
  614.          push ebx esi ebp edx               ; save stuff before centroid handle
  615.          movsx ebx,w [esi+10]               ; no new matrix command, find point
  616.          movsx ecx,w [esi+12]               ; offset (addition)
  617.          movsx ebp,w [esi+14]
  618.  
  619.          call _rotate_point                 ; if found, add _rotate_pointd point to xad,yad,zad
  620.  
  621.          add xad,ebx
  622.          add yad,ecx
  623.          add zad,ebp
  624.  
  625. done_alterq:
  626.          sub zad,1
  627.          adc zad,1
  628.  
  629.          mov ebx,xad                        ; test if new xad,yad,zad are within screen boundaries
  630.          mov ecx,yad
  631.          mov ebp,zad
  632.  
  633.          cmul eax,ebx,ratiox                ; use fast constant multiply fo 3d conversion
  634.          idiv ebp
  635.  
  636.          movsx edx,_xmins
  637.          sub edx,btolr
  638.          cmp eax,edx                        ; tolerance is max object size/ratio
  639.          jl failed_iterationq
  640.          movsx edx,_xmaxs
  641.          add edx,btolr
  642.          cmp eax,edx
  643.          jge failed_iterationq
  644.  
  645.          mov ebx,eax
  646.  
  647.          cmul eax,ecx,ratioy
  648.          idiv ebp
  649.  
  650.          movsx edx,_ymins
  651.          sub edx,btolr
  652.          cmp eax,edx
  653.          jl failed_iterationq
  654.          movsx edx,_ymaxs
  655.          add edx,btolr
  656.          cmp eax,edx
  657.          jge failed_iterationq
  658.  
  659.          mov edi,pointindex
  660.          mov xp[edi],ebx
  661.          mov yp[edi],eax
  662.          mov zp[edi],ebp
  663.          add pointindex,4
  664.  
  665.          pop edx ebp esi ebx
  666.  
  667. done_alter:
  668.          movzx eax,w [esi]                  ; get number of extra points in iteration
  669.          add esi,2
  670.          mov numpoints,eax                  ; set as counter
  671.          mov ecx,eax                        ; save number of extra points for later use
  672.  
  673.          shl eax,2
  674.          add eax,pointindex                 ; pointindex = word indexer to last point
  675.          cmp eax,maxpoints*4                ; test for overflow in points tables
  676.          jae abort_all2
  677.  
  678.          lodsw                              ; get number of sides in iteration
  679.          add numsides,eax
  680.  
  681.          add eax,_showing
  682.          cmp eax,maxsurfaces-1              ; check for overflow in "sides" tables
  683.          jae abort_all2
  684.  
  685.          add esi,25*2
  686.  
  687.          or ecx,ecx                         ; no new points to add? (just surfaces)
  688.          je return_iteration                ; only sides added to iteration, done...
  689.  
  690.          push ebx ebp edx                   ; save load and store locations
  691.  
  692.          mov edi,currobj                    ; add more points to xp,yp,zp list
  693.          mov bl,v_userotate[edi]             ; because iteration is visible
  694.  
  695.          mov edi,pointindex                 ; movzx edi,pointindex
  696.  
  697.          call middle_load_points
  698.          pop edx ebp ebx
  699.  
  700.          jmp return_iteration
  701.  
  702.          align 4
  703.  
  704. abort_all2:
  705.          add esp,strip_bytes                ; abort from iteration and _make1obj
  706.          ret                                ; returning now from _makeobjs call
  707.  
  708. ; perform test for option "onscr" - generate iteration if points on screen.
  709. ; routine also tests if polygon crosses screen - eg no point is on the screen
  710. ; but the polygon covers the screen, like the front of a very big building.
  711.  
  712.          align 4
  713.  
  714. test_if_on_screen:
  715.          xor bl,bl                          ; bl = quadrant flag
  716.          push edx edi                       ; save command
  717.  
  718.          mov esi,ebp
  719. tios:
  720.          mov ecx,xp[esi]                    ; cx, dx =(x,y) to test
  721.          mov edx,yp[esi]
  722.  
  723.          mov ah,32                          ;  32 16  8    determine where point is,
  724.          cmp cx,_xmins                      ;1  x  x  x    then or bl with location
  725.          jl s ytest                         ;2  x  x  x
  726.          mov ah,8                           ;4  x  x  x
  727.          cmp cx,_xmaxs                      ;
  728.          jge s ytest
  729.          mov ah,16
  730. ytest:
  731.          mov al,1
  732.          cmp dx,_ymins
  733.          jl s oritall
  734.          mov al,4
  735.          cmp dx,_ymaxs
  736.          jge s oritall
  737.  
  738.          cmp ah,16
  739.          je s on_screen                     ; a point is on the screen, generate side...
  740. oritall:
  741.          or bl,ah                           ; point is not on the screen, but it may
  742.          or bl,al                           ; contribute to a polygon which covers the screen.
  743.  
  744.          add edi,2                          ; get next connection for another test
  745.          mov si,sides[edi]
  746.          cmp si,bp                          ; test if at last connection in iteration test
  747.          jne tios
  748.  
  749.          xor al,al                          ; count number of bits in y (must be >2)
  750.          ror bl,1
  751.          adc al,0
  752.          ror bl,1
  753.          adc al,0
  754.          ror bl,1
  755.          adc al,0
  756.          cmp al,1
  757.          jbe s skipit2
  758.  
  759.          xor al,al                          ; now count x (must be >2)
  760.          ror bl,1
  761.          adc al,0
  762.          ror bl,1
  763.          adc al,0
  764.          ror bl,1
  765.          adc al,0
  766.          cmp al,1
  767.          jbe s skipit2
  768. on_screen:
  769.          pop edi edx
  770.  
  771.          test edx,both                      ; side is on screen
  772.          jz return_screen                   ; test if alway visible
  773.  
  774.          pop esi ebx ebp                    ; always, pop and test for shading
  775.          test edx,shade
  776.          jz ln2                             ; no shading - do normal return
  777.          jmp handle_shading
  778.  
  779. skipit2:
  780.          pop edi edx esi ebx ebp
  781.          jmp skipit
  782.  
  783. ; handle failure of option 512
  784.  
  785.          align 4
  786.  
  787. failed_iterationq:
  788.          pop edx ebp esi ebx
  789.  
  790. failed_iteration:
  791.          movzx ecx,w [esi+4]                ; number of bytes to skip in case of failure
  792.          mov ax,[esi+6]                     ; get number of points TOTAL in iteration
  793.          add esi,8
  794.          shl eax,2                          ; in case iteration in iteration in iteration...
  795.          add w pointindex,ax
  796.          add esi,ecx
  797.          jmp return_iteration
  798.  
  799.          align 4
  800.  
  801. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  802. ; _make1obj: Handle plotting of object ESI
  803. ; In:
  804. ;   ESI -> object #
  805. ; OUT:null
  806. ; Notes:
  807. ; Routine assumes object is already ON!  note: esi not si!
  808. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  809.  
  810. _make1obj:
  811.          mov currobj,esi
  812.  
  813.          mov ebx,v_xs[esi*4]                 ; displacement
  814.          sub ebx,eyex
  815.          mov ecx,v_ys[esi*4]
  816.          sub ecx,eyey
  817.          mov ebp,v_zs[esi*4]
  818.          sub ebp,eyez
  819.  
  820.          test v_userotate[esi],s_himap+s_point ; check if _bitmap or point
  821.          jnz mo_special
  822.  
  823.          if div_256 eq 8
  824.          shr ebx,8                          ; account for decimal places
  825.          test ebx,00800000h
  826.          jz s pm_1
  827.          or ebx, 0ff000000h
  828. pm_1:
  829.          shr ecx,8
  830.          test ecx,00800000h
  831.          jz s pm_2
  832.          or ecx, 0ff000000h
  833. pm_2:
  834.          shr ebp,8
  835.          test ebp,00800000h
  836.          jz s pm_3
  837.          or ebp, 0ff000000h
  838. pm_3:
  839.          endif
  840.  
  841.          mov si,v_whatshape[esi*2]           ; get shape
  842.          mov esi,_objbase[esi*4]            ; get header start
  843.          add esi,[esi+4]                    ; get first resolution
  844.          mov edi,[esi+14*2]                 ; get maximum distance seen
  845.  
  846.          cmp ebx,edi                        ; check if within visible space
  847.          jnl s noa2                         ; if object miles away, don't bother
  848.          cmp ebp,edi
  849.          jnl s noa2
  850.          cmp ecx,edi
  851.          jnl s noa2
  852.          neg edi
  853.          cmp ebp,edi
  854.          jl s noa2
  855.          cmp ebx,edi
  856.          jl s noa2
  857.          cmp ecx,edi
  858.          jg s mo_misout
  859. noa2:
  860.          ret
  861. mo_misout:
  862.          mov edi,dword ptr [esi+16*2]
  863.          mov eax,dword ptr [esi+18*2]
  864.          mov btolr,eax
  865.          call _zsolve                       ; figure out camera displacement
  866.  
  867.          cmp esi,edi                        ; check if behind camera, miminum dist.
  868.          jl s noa2
  869.  
  870.          sub esi,1                          ; make z non-zero
  871.          adc esi,1
  872.  
  873.          call _xsolve
  874.          mov xad,edi                        ; store 3d offsets
  875.          call _make3dx                      ; now make object farther in 3d
  876.  
  877.          movsx eax,_xmins
  878.          sub eax,btolr
  879.          cmp edi,eax                        ; tolerance is max object size/ratio
  880.          jl s noa2
  881.          movsx eax,_xmaxs
  882.          add eax,btolr
  883.          cmp edi,eax
  884.          jge s noa2
  885.  
  886.          call _ysolve                       ; solve y and set correct regs
  887.          mov yad,ecx
  888.          call _make3dy                      ; now make object farther in 3d
  889.  
  890.          movsx eax,_ymins
  891.          sub eax,btolr
  892.          cmp ecx,eax
  893.          jl s noa2
  894.          movsx eax,_ymaxs
  895.          add eax,btolr
  896.          cmp ecx,eax
  897.          jge noa2
  898.  
  899.          mov zad,ebp
  900.          mov esi,pointindex
  901.  
  902.          mov xp[esi],ebx                    ; save center of gravity as point 0
  903.          mov yp[esi],ecx
  904.          mov zp[esi],ebp
  905.  
  906.          mov esi,currobj                    ; pop original object number
  907.          xor ebx,ebx
  908.          mov bl,v_palxref[esi]
  909.          mov ebx,_xreftable[ebx*4]
  910.          mov palxrefx,ebx
  911.  
  912.          test v_userotate[esi],no_rotation   ; test to call _compound routine
  913.          jnz s mk_skipc                     ; skip if anything other than full rotations
  914.          call _compound                     ; full rotation object, calc. matrix
  915. mk_skipc:
  916.          call loadpoints                    ; load points and _rotate_point, exit di=sides
  917.          jmp loadsides                      ; now load sides, starting at di
  918.  
  919.          align 4
  920. noa:
  921.          ret
  922.  
  923.          align 4
  924.  
  925. ; if v_userotate = 32 then draw _bitmap at location x,y,z
  926.  
  927. mo_special:
  928.          mov edi,maxz*256
  929.          cmp ebx,edi                        ; check if within visible space
  930.          jnl s noa                          ; if object miles away, don't bother
  931.          cmp ebp,edi
  932.          jnl s noa
  933.          cmp ecx,edi
  934.          jnl s noa
  935.          neg edi
  936.          cmp ebp,edi
  937.          jl s noa
  938.          cmp ebx,edi
  939.          jl s noa
  940.          cmp ecx,edi
  941.          jl s noa
  942.  
  943.          if div_256 eq 8
  944.          shr ebx,8                          ; account for decimal places, /256
  945.          test ebx,00800000h
  946.          jz s pq_1
  947.          or ebx, 0ff000000h
  948. pq_1:
  949.          shr ecx,8
  950.          test ecx,00800000h
  951.          jz s pq_2
  952.          or ecx, 0ff000000h
  953. pq_2:
  954.          shr ebp,8
  955.          test ebp,00800000h
  956.          jz s pq_3
  957.          or ebp, 0ff000000h
  958. pq_3:
  959.          endif
  960.  
  961.          call _zsolve                       ; figure out camera displacement
  962.  
  963.          cmp esi,minz                       ; check if behind camera, miminum dist.
  964.          jl noa
  965.  
  966.          call _xsolve
  967.          mov xad,edi                        ; store 3d offsets
  968.          call _make3dx                      ; now make object farther in 3d
  969.  
  970.          cmp edi,xmit                       ; tolerance is max object size/ratio
  971.          jl noa
  972.          cmp edi,xmat
  973.          jge noa
  974.  
  975.          call _ysolve                       ; solve y and set correct regs
  976.          mov yad,ecx
  977.          call _make3dy                      ; now make object farther in 3d
  978.  
  979.          cmp ecx,ymit
  980.          jl noa
  981.          cmp ecx,ymat
  982.          jge noa
  983.  
  984.          mov zad,ebp
  985.          mov esi,currobj                    ; pop original object number
  986.  
  987.          cmp pointindex,(maxpoints-1)*2     ; check if there is room in table
  988.          jge noa
  989.          cmp _showing,maxsurfaces-1
  990.          jge noa
  991.  
  992.          test v_userotate[esi],s_point       ; is point or _bitmap?
  993.          jnz mo_ispoint
  994.  
  995.          mov edi,pointindex
  996.          mov [xp+edi],ebx                   ; set location of _bitmap
  997.          mov [yp+edi],ecx
  998.          mov [zp+edi],ebp
  999.  
  1000.          mov edi,offsides
  1001.          add offsides,maxpolys*2            ; update for next object/_bitmap
  1002.  
  1003.          mov ebx,_showing
  1004.          shl ebp,2                          ; adjust so it's the same as loadsides
  1005.          mov zeds[ebx*4],ebp                ; set z sort indexer
  1006.  
  1007.          inc _showing                       ; one more surface...
  1008.          xor ah,ah
  1009.          mov al,v_userotate[esi]
  1010.          mov textures[ebx*2],ax             ; set command for _bitmap
  1011.  
  1012.          mov eax,pointindex
  1013.          add pointindex,4
  1014.          stosw
  1015.          mov ax,v_whatshape[esi*2]
  1016.          stosw
  1017.          mov ax,v_bitobjx[esi*2]             ; set x and y scales (stretching)
  1018.          stosw
  1019.          mov ax,v_bitobjy[esi*2]
  1020.          stosw
  1021. noa4:
  1022.          ret
  1023.  
  1024.          align 4
  1025.  
  1026. mo_ispoint:
  1027.          cmp bx,_xmins                      ; draw single point/bullet
  1028.          jl s noa4
  1029.          cmp bx,_xmaxs
  1030.          jge s noa4
  1031.          cmp cx,_ymins
  1032.          jl s noa4
  1033.          cmp cx,_ymaxs                      ; _ymaxs1 if larger pixel
  1034.          jge s noa4
  1035.  
  1036.          mov edi,pointindex
  1037.          mov [xp+edi],ebx                   ; set location of point/_bitmap
  1038.          mov [yp+edi],ecx
  1039.          mov [zp+edi],ebp
  1040.  
  1041.          mov edi,offsides
  1042.          add offsides,maxpolys*2            ; update for next object/_bitmap
  1043.  
  1044.          mov ebx,_showing
  1045.          shl ebx,1
  1046.          shl ebp,2
  1047.          mov zeds[ebx*2],ebp                ; set z sort indexer
  1048.  
  1049.          inc _showing                       ; one more surface...
  1050.  
  1051.          mov textures[ebx],64               ; set this command as point
  1052.          mov surfcolors[ebx],bulletcolour   ; only for variable colours
  1053.  
  1054.          mov eax,pointindex
  1055.          add pointindex,4
  1056.  
  1057.          stosw
  1058.          stosw
  1059. noa8:
  1060.          ret
  1061.  
  1062.          align 4
  1063.  
  1064. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1065. ; Set_order: Initialize original order for plotting objects
  1066. ;  In=Out=null
  1067. ; Notes:  This is called by _flush_surfaces so no need for you to do it.
  1068. ; This must be called every frame to re-initalize the order for polygon sorting
  1069. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1070.  
  1071. set_order:
  1072.          mov ecx,_showing
  1073.          jcxz s non2_do
  1074.          dec ecx
  1075.          jz s non2_do
  1076.          shl ecx,1
  1077.          mov esi,ecx
  1078.          shl esi,1
  1079.          add esi,offset order
  1080.  
  1081.          prc equ 8
  1082.  
  1083.          cmp ecx,prc*2
  1084.          jb s ordrloop
  1085. bigsloop:
  1086.          i=0
  1087.          rept prc
  1088.          mov [esi+i],ecx
  1089.          i=i-4
  1090.          sub ecx,2
  1091.          endm
  1092.          jz s non2_do
  1093.          sub esi,prc*4
  1094.          cmp ecx,prc*2
  1095.          jae s bigsloop
  1096. ordrloop:
  1097.          mov [esi],ecx
  1098.          sub esi,4
  1099.          dec ecx
  1100.          loop ordrloop
  1101. non2_do:
  1102.          mov [order],0                      ; fill last
  1103.  
  1104.          ret
  1105.  
  1106.          align 4
  1107.  
  1108. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1109. ; _makeobjs: Make/plot all objects on _current_page, unrolled loop
  1110. ;  In=Out=null
  1111. ; Notes: Called from _makeobjs
  1112. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1113.  
  1114. makeobjx:
  1115.          i=1
  1116.  
  1117.          rept maxobjects
  1118.          local itsoff
  1119.  
  1120.          test v_onoff+i,mainobject_on        ; check on/off
  1121.          jz s itsoff
  1122.  
  1123.          mov esi,i
  1124.          call _make1obj
  1125. itsoff:
  1126.  
  1127.          i=i+1
  1128.          endm
  1129.  
  1130.          ret                                ; put no code here! _make1obj may force abort!
  1131.  
  1132. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1133. ; _init_tables: Initialize ordering before beginning 3d animation
  1134. ;  In=Out=null
  1135. ; Notes: Called by YOU. Different routines between 3d1,3d2 and 3d3
  1136. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1137.  
  1138. _init_tables:
  1139.          mov offsides, offset sides         ; clear table indexers for call
  1140.          mov pointindex,0
  1141.          mov _showing,0
  1142.          ret
  1143.  
  1144.          align 4
  1145.  
  1146. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1147. ; _makeobjs: Make/plot all objects on _current_page
  1148. ;  In=Out=null
  1149. ; Notes: Called from your mainline animation routine, falls through to _flush_surfaces
  1150. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1151. _makeobjs:
  1152.          call makeobjx                      ; make objects
  1153.  
  1154. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1155. ; _flush_surfaces: Sort and flush all surfaces from polygon buffer to screen
  1156. ;  In=Out=null
  1157. ; Notes: called by _makeobjs
  1158. ;░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
  1159.  
  1160. _flush_surfaces:
  1161.          call set_order                     ; set ordering of sides
  1162.          call _sortlist                     ; sort sides according to z distance
  1163.          call _drawvect                     ; draw 'em on da screen
  1164.  
  1165.          mov offsides, offset sides         ; clear table indexers for call
  1166.          mov pointindex,0
  1167.  
  1168.          ret
  1169.  
  1170. code32   ends
  1171.          end
  1172.